﻿using System;
using System.IO;
using System.Xml;
using System.Data;
using System.Linq;
using System.Text;
using System.Drawing;
using System.ComponentModel;
using System.Data.OleDb;
using System.Windows.Forms;
using System.Threading.Tasks;
using System.Collections;
using System.Collections.Generic;
using DevComponents.DotNetBar;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.ConversionTools;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.DataSourcesRaster;
using PlanningGIS.Util;
using PlanningGIS.ArcGIS.Custom;
using PlanningGIS.Win.Controls;
using PlanningGIS.Util.IO;
using PlanningGIS.Access;
using PlanningGIS.Util.Serialization;
using PlanningGIS.MapSheet;
using PlanningGIS.Framework;
using PlanningGIS.Engine.Controls;
using PlanningGIS.ArcGIS;
using PlanningGIS.Util.Log;
using PlanningGIS.Util.Data;
using PlanningGIS.MetaData;
using System.Runtime.InteropServices;
using PlanningGIS.Util.Convertor;
using System.Text.RegularExpressions;
using PlanningGIS.Framework.Config;

namespace PlanningGIS.Product
{
    /// <summary>
    /// 元数据录入
    /// </summary>
    public partial class FrmMetaData : Office2007Form
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        public FrmMetaData()
        {
            InitializeComponent();
            dataGridView.AllowUserToDeleteRows = false;//使用del删除后在保存带有空间的模板时会报“查询过于复制”的错误
        }
        
        /// <summary>
        /// 加载窗体
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FrmMetaData_Load(object sender, EventArgs e)
        {            
            try
            {
                cmbRank.ValueMember = "Value";
                cmbRank.DisplayMember = "Name";
                cmbRank.DataSource = MetaDataType.GetRanks(ProductHelper.ProductConfig.DataTypes);
                cmbRank.SelectedIndex = 0;
                _pgrsor = new Progressor() { ProgressBar = prgbar };
                string metaEnumFile = ProductHelper.ProductPath + "\\MetaEnum.xml";
                if (File.Exists(metaEnumFile))
                    metaEnums = (List<MetaEnum>)XmlSerialization.Deserialize<List<MetaEnum>>(metaEnumFile, null);
                string rulename = ProductHelper.ProductPath + "\\ReadRule.xml";
                if (File.Exists(rulename))
                    _ReadRule = (List<ValueName>)XmlSerialization.Deserialize<List<ValueName>>(rulename, null);
                if (SheetHelper.Config == null) SheetHelper.Config = ConfigHelper.GetObject<SheetConfig>();
                swtSizeType.Value = String.Equals(SheetHelper.Config.CurrentSize, "50X40", StringComparison.CurrentCultureIgnoreCase);
            }
            catch (Exception ex)
            {
                MsgHelper.ShowErrorMsgbox(this, ex.Message);
            }
        }

        /// <summary>
        /// 进度条
        /// </summary>
        private Progressor _pgrsor = null;

        /// <summary>
        /// mdb数据库操作
        /// </summary>
        private IDbContext dbContext = null;     
   
        /// <summary>
        /// 元数据枚举项数据源
        /// </summary>
        private List<MetaEnum> metaEnums = null;

        /// <summary>
        /// 当前选择的数据类型
        /// </summary>
        private MetaDataType _SelDType = null;

        /// <summary>
        /// 选择的数据源中的所有数据表名称
        /// </summary>
        private List<string> _TableNames = null;

        /// <summary>
        /// 选择的表中的字段
        /// </summary>
        private List<MetaField> _RuleFields = null;

        /// <summary>
        /// 产品元数据读取规则
        /// </summary>
        private List<ValueName> _ReadRule { get; set; }

        /// <summary>
        /// 当前查询的SQL，在保存是使用
        /// </summary>
        private string _QuerySQL = "";

        /// <summary>
        /// 创建，并保存修改
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnCreate_Click(object sender, EventArgs e)
        {
            saveFileDialog.Filter = "Access文件(*.mdb)|*.mdb";
            saveFileDialog.FileName = "元数据文件";
            if (saveFileDialog.ShowDialog() != DialogResult.OK) return;
            this.Cursor = Cursors.WaitCursor;
            try
            { 
                Save();
                dataGridView.DataSource = null;
                _TableNames = null;
                string fname = saveFileDialog.FileName;
                if (System.IO.File.Exists(fname)) System.IO.File.Delete(fname);
                txtFile.Text = fname;
                File.Copy(ProductHelper.ProductPath + "\\元数据模板.mdb", fname);
                Application.DoEvents();
                SetSource(fname); 
            }
            catch (System.Exception ex)
            {
                MsgHelper.ShowErrorMsgbox(this, "文件被占用，覆盖失败！" + ex.Message);
            }
            finally
            {
                this.Cursor = Cursors.Default;
            }
        }
        
        /// <summary>
        /// 打开元数据文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnOpen_Click(object sender, EventArgs e)
        {
            openFileDialog.Filter = "mdb文件(*.mdb)|*.mdb";
            openFileDialog.Multiselect = false;
            if (openFileDialog.ShowDialog() != DialogResult.OK) return;
            this.Cursor = Cursors.WaitCursor;
            try
            {
                Save();
                dataGridView.DataSource = null;
                _TableNames = null;
                string fname = openFileDialog.FileName;
                txtFile.Text = fname;                
                SetSource(fname);            
            }
            catch (System.Exception err)
            {
                MsgHelper.ShowErrorMsgbox(this, "打开数据文件失败：" + err.Message);
            }
            finally
            {
                this.Cursor = Cursors.Default;
            }
        }

        /// <summary>
        /// 选择数据库等级
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cmbRank_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cmbRank.SelectedValue == null) return;
            cmbDataType.ValueMember = "TableName";
            cmbDataType.DisplayMember = "DataType";
            cmbDataType.DataSource = MetaDataType.GetDataTypes(ProductHelper.ProductConfig.DataTypes, cmbRank.SelectedValue.ToString());
            cmbDataType.SelectedIndex = 0;
        }

        /// <summary>
        /// 数据类型选择改变
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cmbDataType_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cmbDataType.SelectedValue == null) return;
            Save();
            SetTableName();
        }

        /// <summary>
        /// 更换数据源后重新进行设置
        /// </summary>
        /// <param name="fullname">数据源路径</param>
        private void SetSource(string fullname)
        {
            dbContext = new AccessContext(fullname);
            //默认选择mdb中的符合名称规范第一张表
            _TableNames = dbContext.GetTableNames();
            if (_TableNames == null || _TableNames.Count == 0)
            {
                MsgHelper.ShowErrorMsgbox(this, fullname+"中不存在数据表，请重新选择！");
                return;
            }
            MetaDataType ty = ProductHelper.ProductConfig.DataTypes.FirstOrDefault(t => _TableNames.Contains(t.TableName.Trim().ToUpper()));
            if (ty == null || string.IsNullOrWhiteSpace(ty.DataType))
            {
                MsgHelper.ShowErrorMsgbox(this, fullname + "中不存在满足要求的数据表，请重新选择！\n如DLG图幅数据的表名格式为：MD_TF_DLG；其他类似。");
                return;
            }
            cmbRank.SelectedValue = ty.Rank.ToString();
            cmbDataType.ValueMember = "TableName";
            cmbDataType.DisplayMember = "DataType";
            cmbDataType.DataSource = MetaDataType.GetDataTypes(ProductHelper.ProductConfig.DataTypes, ty.Rank);
            cmbDataType.SelectedValue = ty.TableName;
        }

        /// <summary>
        /// 设置当前操作的数据表对象
        /// </summary>
        private void SetTableName()
        {
            dataGridView.DataSource = null;
            cmbColumn.DataSource = null;
            dataGridView.Columns.Clear();
            _SelDType = null;
            dataGridView.AutoGenerateColumns = false;
            if (dbContext == null) return;
            if (cmbDataType.SelectedValue == null) return;
            if (_TableNames == null || _TableNames.Count == 0) return;
            _SelDType = (MetaDataType)cmbDataType.SelectedItem;
            if (!_TableNames.Contains(_SelDType.TableName.Trim().ToUpper()))
            {
                LogHelper.WriteErrLog("数据表" + _SelDType.TableName + "不存在");
                return;
            }
            try
            {
                CreateColumns();
                var vo = from itm in _RuleFields
                         select itm.Name;
                List<string> ns = vo.ToList();
                string qn = "";
                foreach (string s in ns) qn += "," + s;
                qn = qn.Substring(1);
                _QuerySQL = "select " + qn + " from " + _SelDType.TableName;
                dataGridView.DataSource = dbContext.GetDataTable(_QuerySQL);
            }
            catch (Exception ex)
            {
                LogHelper.WriteErrLog("操作异常，可能是由于数据表" + _SelDType.TableName + "不存在：" + ex.Message);
                return;
            }
            finally
            {
                this.Cursor = Cursors.Default;
            }
        }

        /// <summary>
        /// 创建数据列
        /// </summary>
        private void CreateColumns()
        {
            List<DbFieldInfo> fields = dbContext.GetFieldInfos(_SelDType.TableName);
            if (fields == null || fields.Count == 0) return;
            fields.RemoveAll(t => ProductHelper.NoQueryFields.Exists(p => p.Equals(t.Name, StringComparison.CurrentCultureIgnoreCase)));
            MetaRule rule = null;
            if (ProductHelper.MetaRules != null && ProductHelper.MetaRules.Count > 0) 
                rule = ProductHelper.MetaRules.FirstOrDefault(t => t.TableName.Equals(_SelDType.TableName, StringComparison.CurrentCultureIgnoreCase));
            _RuleFields = new List<MetaField>();
            foreach (DbFieldInfo f in fields)
            {
                if (ProductHelper.FilterFields.Exists(t => t.Equals(f.Name, StringComparison.CurrentCultureIgnoreCase))) continue;                
                bool nullable = f.Nullable;
                if (nullable) 
                    if (ProductHelper.NoNullFields.Exists(t => t.Equals(f.Name, StringComparison.CurrentCultureIgnoreCase))) nullable = false;
                string des = f.Name;
                MetaField md = null;                
                if (rule != null && rule.Fields != null && rule.Fields.Count > 0)
                    md = rule.Fields.FirstOrDefault(t => t.Name.Equals(f.Name, StringComparison.CurrentCultureIgnoreCase));
                if (md != null && !string.IsNullOrWhiteSpace(md.Alias)) des = md.Alias;
                foreach (string s in ProductHelper.NoHasString)
                    des = des.Replace(s, "_");                
                bool visible = !ProductHelper.VisibleString.Exists(t => f.Name.ToUpper().Contains(t.ToUpper()));
                int idx = dataGridView.Columns.Add(f.Name, des);
                dataGridView.Columns[idx].Visible = visible;
                dataGridView.Columns[idx].DataPropertyName = f.Name;
                if (!nullable) dataGridView.Columns[f.Name].DefaultCellStyle.BackColor = Color.YellowGreen;
                MetaField newmd = new MetaField() { Name = f.Name, Visible = visible, Alias = des, AllowNull = nullable };
                if (md != null)
                {
                    newmd.AutoValueType = md.AutoValueType;
                    newmd.FieldType = md.FieldType;
                }
                _RuleFields.Add(newmd);                
            }
            SetColumn();
            
        }

        /// <summary>
        /// 设置字段规则信息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnRule_Click(object sender, EventArgs e)
        {
            if (_SelDType == null || _RuleFields == null) return;
            FrmMetaRule frm = new FrmMetaRule(_SelDType.TableName,_RuleFields);
            if (frm.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
            {
                _RuleFields = frm.SelFields;
                if (_RuleFields == null || _RuleFields.Count == 0) return;
                foreach (MetaField fd in _RuleFields)
                {
                    dataGridView.Columns[fd.Name].Visible = fd.Visible;
                }
                SetColumn();
            }
        }

        /// <summary>
        /// 仅显示可见列
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void chkOnlyVisiable_CheckedChanged(object sender, EventArgs e)
        {
            if (dataGridView.Columns.Count > 0)
            {
                foreach (DataGridViewColumn col in dataGridView.Columns)
                    col.Visible = chkOnlyVisiable.Checked ? (bool)col.Tag : true;
            }
            if (cmbColumn.DataSource != null && cmbColumn.DataSource is List<ValueName2>)
            {
                SetColumn();
            }
        }
        
        /// <summary>
        /// 设置列名
        /// </summary>
        /// <param name="fields"></param>
        /// <param name="onlyvisiable"></param>
        private void SetColumn()
        {
            if (_RuleFields == null || _RuleFields.Count == 0) return;
            cmbColumn.ValueMember = "Name";
            cmbColumn.DisplayMember = "Name";
            if (chkOnlyVisiable.Checked)
                cmbColumn.DataSource = _RuleFields.FindAll(t => t.Visible);
            else
                cmbColumn.DataSource = _RuleFields;
            cmbColumn.SelectedIndex = 0;
            var v = from f in _RuleFields
                    select f.Name;
            AutoCompleteStringCollection col = new AutoCompleteStringCollection();
            List<string> lst = v.ToList();
            foreach (string s in lst) col.Add(s);
            cmbColumn.AutoCompleteCustomSource = col;
        }

        /// <summary>
        /// 保存之前的编辑
        /// </summary>
        /// <param name="checkchange">是否检查修改，false不检查，直接保存</param>
        private void Save(bool checkchange = false)
        {
            if (_SelDType == null) return;
            if (dataGridView.DataSource == null || dbContext == null) return;
            DataTable dt = dataGridView.DataSource as DataTable;
            if (dt == null) return;
            foreach (DataGridViewColumn c in dataGridView.Columns)  //不加该操作，则在保存时会报锁定的异常
                c.Frozen = false;
            //DataTable tmpdt = dt.GetChanges();
            //if (tmpdt == null) return;
            if (checkchange)
                if (MsgHelper.ShowYesOrNoQueryMsgBox("数据已修改，是否保存修改?",this) != DialogResult.Yes) return;
            this.Cursor = Cursors.WaitCursor;
            try
            {
                if (dt.Rows.Count == 0)
                    dbContext.ExecuteNonQuery("delete from " + _SelDType.TableName);
                else
                    dbContext.UpdateDataTable(dt, _QuerySQL);
                Application.DoEvents();
                dataGridView.DataSource = dt;
            }
            catch(Exception ex)
            {
                LogHelper.WriteErrorText(ex);
                MsgHelper.ShowErrorMsgbox(this, "保存失败！");
            }
            finally
            {
                this.Cursor = Cursors.Default;
            }
        }

        /// <summary>
        /// 点击列标题
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dataGridView_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Right)
            {
                
            }
            else if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                chkOnlySel.Checked = false;
                SetColumnIndex(e.ColumnIndex);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dataGridView_CellMouseUp(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.RowIndex == -1) return;
            if (dataGridView.SelectedCells.Count == 0) return;
            int idx = -1;
            foreach (DataGridViewCell cell in dataGridView.SelectedCells)
            {
                if (idx == -1) idx = cell.ColumnIndex;
                else
                {
                    if (idx != cell.ColumnIndex) return;
                }
            }
            chkOnlySel.Checked = true;
            SetColumnIndex(idx);
        }

        /// <summary>
        /// 设置列
        /// </summary>
        /// <param name="idx"></param>
        private void SetColumnIndex(int idx)
        {
            cmbColumn.SelectedValue = dataGridView.Columns[idx].Name;
             
            //List<MetaField> source = cmbColumn.DataSource as List<MetaField>;
            //for (int i = 0; i < source.Count; i++)
            //{
            //    if (source[i].Name.Equals(name, StringComparison.CurrentCultureIgnoreCase))
            //    {
            //        cmbColumn.SelectedIndex = i;
            //        break;
            //    }
            //}
        }

        /// <summary>
        /// 选择列
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cmbColumn_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cmbColumn.SelectedValue == null) return;
            string colname = cmbColumn.SelectedValue.ToString();
            if (string.IsNullOrWhiteSpace(colname)) return;
            if (dataGridView.DataSource == null) return;
            if (metaEnums != null && metaEnums.Count > 0)
            {
                MetaEnum em = metaEnums.Find(t => t.FieldName.Equals(colname, StringComparison.CurrentCultureIgnoreCase)
                    && (t.SourceName.Equals(_SelDType.DataType.ToString(), StringComparison.CurrentCultureIgnoreCase)
                    || t.SourceName.Equals(_SelDType.TableName, StringComparison.CurrentCultureIgnoreCase)));
                if (em != null)
                {
                    iptColValue.DataSource = em.Values;
                    if (em.AllowExpand) iptColValue.Init(InputDataType.zjgisDataType.EnumExpand);
                    else iptColValue.Init(InputDataType.zjgisDataType.Enum);
                    return;
                }
            }
            iptColValue.Init((dataGridView.DataSource as DataTable).Columns[colname].DataType);
        }

        /// <summary>
        /// 按下Entry键，确认修改
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void iptColValue_EntryPress(object sender, EventArgs e)
        {
            btnUpdateColumn_Click(null, null);
        }

        /// <summary>
        /// 更新指定的列的值
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnUpdateColumn_Click(object sender, EventArgs e)
        {
            if (cmbColumn.SelectedValue == null || string.IsNullOrWhiteSpace(cmbColumn.SelectedValue.ToString())) return;
            string colname = cmbColumn.SelectedValue.ToString();
            if (dataGridView.Columns[colname] == null) return;
            if (dataGridView.Columns[colname].ReadOnly) return;
            DataTable dt = dataGridView.DataSource as DataTable;
            if (dt == null) return;
            dynamic value = iptColValue.Value;
            for (int i = 0; i < dataGridView.Rows.Count; i++)
            {
                if (dataGridView.Rows[i].IsNewRow) continue;
                if (chkOnlySel.Checked)
                    if (!dataGridView.Rows[i].Cells[colname].Selected) continue;
                dataGridView.Rows[i].Cells[colname].Value = value;
            }
            //if (iptColValue.Expanded)
            //{

            //}
        }

        /// <summary>
        /// 从产品文件名读图号
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnGetThFromDwg_Click(object sender, EventArgs e)
        {
            ReadTHFormFile();
        }
        
        /// <summary>
        /// 从文件中读取图号
        /// </summary>
        private void ReadTHFormFile()
        {
            if (dataGridView.DataSource == null) return;
            if (_SelDType == null) return;
            string ext = _SelDType.Extensions.Replace(",", ";");
            if (string.IsNullOrEmpty(ext))
                ext = "所有文件(*.*)|*.*";
            else
            {
                if (ext.Trim().EndsWith(";")) ext = ext.Trim().Substring(0, ext.Trim().Length - 1);
                if (!ext.Trim().StartsWith("*")) ext = "*" + ext;
                ext = _SelDType.DataType.ToString() + "文件(" + ext + ")|" + ext;
            }
            openFileDialog.Filter = ext;
            openFileDialog.FileName = "";
            openFileDialog.Multiselect = true;
            if (openFileDialog.ShowDialog() != DialogResult.OK) return;
            string[] files = openFileDialog.FileNames;
            this.Cursor = Cursors.WaitCursor;            
            try
            {
                _pgrsor.SetMaxValue(files.Length);
                string rname = PlanningGIS.MetaData.MetaHelper.FindName(_SelDType.Rank.ToString(), PlanningGIS.MetaData.MetaHelper.KEY);
                DataTable dt = dataGridView.DataSource as DataTable;
                dataGridView.AllowUserToAddRows = false;
                foreach (string fi in files)
                {
                    _pgrsor.Step();
                    DataRow dr = dt.NewRow();
                    dr[rname] = System.IO.Path.GetFileNameWithoutExtension(fi);
                    dr[MetaHelper.ID] = Guid.NewGuid().ToString();
                    dt.Rows.Add(dr);
                    dataGridView.Rows[dt.Rows.Count - 1].Tag = fi;                    
                }
                dataGridView.AllowUserToAddRows = true;
                _pgrsor.Stop();
            }
            catch (System.Exception ex)
            {
                MsgHelper.ShowErrorMsgbox(this, ex.Message);
            }
            finally
            {
                this.Cursor = Cursors.Default;
            }
        }

        /// <summary>
        /// 从产品文件名读元数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnTHMeta_Click(object sender, EventArgs e)
        {
            if (_ReadRule == null || _ReadRule.Count == 0) return;
            if (dataGridView.Rows.Count == 0) return;
            dataGridView.AllowUserToAddRows = false;
            _pgrsor.SetMaxValue(dataGridView.Rows.Count);
            foreach (DataGridViewRow r in dataGridView.Rows)
            {
                _pgrsor.Step();
                if (r.IsNewRow || r.Tag == null || !(r.Tag is string)) continue;
                List<string> values = ReadTextFormDwg((string)r.Tag);
                if (values == null || values.Count == 0) return;
                foreach (ValueName vm in _ReadRule)
                {
                    string s1 = vm.Value;
                    string s2 = vm.Value;
                    if (vm.Value.Contains("$"))
                    {
                        string[] s = vm.Value.Split('$');
                        if (s.Length == 2)
                        {
                            s1 = s[0];
                            s2 = s[1];
                        }
                    }
                    string v = values.FirstOrDefault(t => t.ToUpper().RemoveChar(' ').ToDBC().Contains(s1.ToUpper().RemoveChar(' ').ToDBC()));
                    try
                    {
                        if (string.IsNullOrWhiteSpace(v)) continue;
                        v = v.RemoveChar(' ').ToDBC();
                        //if (vm.Name.Equals(MetaHelper.BLCFM, StringComparison.CurrentCultureIgnoreCase))
                        //{
                        //    v = StringHelper.ToDBC(v.Replace(" ", "").Replace("1:", ""));
                        //}
                        //if (vm.Name.Equals(MetaHelper.SCRQ, StringComparison.CurrentCultureIgnoreCase))
                        //{
                        //    if (!string.IsNullOrWhiteSpace(s2))
                        //    {
                        //        Regex rg = new Regex(s2);
                        //        Match mh = rg.Match(v);
                        //        if (mh.Success && mh != null && mh.Groups.Count > 0) v = mh.ToString();
                        //    }
                        //}
                        string result = "";
                        if (!string.IsNullOrWhiteSpace(s2))
                        {
                            Regex rg = new Regex(s2);
                            Match mh = rg.Match(v);
                            if (mh.Success && mh != null && mh.Groups.Count > 0) result = mh.ToString();
                        }
                        if (r.Cells[vm.Name] != null) r.Cells[vm.Name].Value = result.Trim();
                        else LogHelper.WriteErrLog("元数据字段：" + vm.Name + "不存在，无法赋值。");
                    }
                    catch (Exception ex)
                    {
                        LogHelper.WriteErrLog("给字段" + vm.Name + "赋值" + v + "失败:" + ex.Message);
                    }
                }
            }
            dataGridView.AllowUserToAddRows = true;
            _pgrsor.Stop();

        }

        /// <summary>
        /// 设置读取产品元数据的规则
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnMetaSet_Click(object sender, EventArgs e)
        {
            FrmMetaInfoSet frm = new FrmMetaInfoSet(_RuleFields);
            frm.ReadRule = _ReadRule;
            if (frm.ShowDialog(this) != System.Windows.Forms.DialogResult.OK) return;
            _ReadRule = frm.ReadRule;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="filename"></param>
        /// <returns></returns>
        private List<string> ReadTextFormDwg(string filename)
        {
            try
            {
                List<IFeatureClass> clses = CadHelper.GetFeatureClasses(filename);
                if (clses == null || clses.Count == 0) return null;
                IFeatureClass cls = clses.FirstOrDefault(e => e.FeatureType == esriFeatureType.esriFTCoverageAnnotation);
                if (cls == null) return null;
                int idx = cls.Fields.FindField("Text");
                if (idx < 0) return null;
                List<string> values = new List<string>();
                IFeatureCursor cur = cls.Search(null, false);
                IFeature feat = null;
                while ((feat = cur.NextFeature()) != null)
                {
                    object o = feat.get_Value(idx);
                    string v = o == null ? "" : o.ToString();
                    if (string.IsNullOrWhiteSpace(v)) continue;
                    //v = StringHelper.ToDBC(v.Replace(" ", ""));
                    values.Add(v);
                }
                Marshal.ReleaseComObject(cur);
                cur = null;
                return values;
            }
            catch (Exception ex)
            {
                LogHelper.WriteErrLog("读取文件" + filename + "失败：" + ex.Message);
                return null;
            }
        }
    
        /// <summary>
        /// 从文本文件中读图号
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnGetThFromTxt_Click(object sender, EventArgs e)
        {
            if (dataGridView.DataSource == null) return;
            openFileDialog.Filter = "文本文件(*.txt;*.dat)|*.txt;*.dat";
            openFileDialog.Multiselect = false;
            if (openFileDialog.ShowDialog() != DialogResult.OK) return;
            this.Cursor = Cursors.WaitCursor;
            StreamReader reader = null;
            try
            {
                string rname = PlanningGIS.MetaData.MetaHelper.FindName(_SelDType.Rank.ToString(), PlanningGIS.MetaData.MetaHelper.KEY);
                DataTable dt = dataGridView.DataSource as DataTable;
                reader = new StreamReader(openFileDialog.FileName, Encoding.Default);
                string th = "";
                dataGridView.AllowUserToAddRows = false;
                while ((th = reader.ReadLine()) != null)
                {
                    if (string.IsNullOrEmpty(th)) continue;                    
                    DataRow dr = dt.NewRow();
                    dr[rname] = th;
                    dr[MetaHelper.ID] = Guid.NewGuid().ToString();
                    dt.Rows.Add(dr);
                }
                dataGridView.AllowUserToAddRows = true;
            }
            catch (System.Exception ex)
            {
                MsgHelper.ShowErrorMsgbox(this, ex.Message);
            }
            finally
            {
                reader.Close();
                reader.Dispose();
                reader = null;
                this.Cursor = Cursors.Default;
            }
        }

        #region 导入XML
        /// <summary>
        /// 导入XML
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnImport_Click(object sender, EventArgs e)
        {
            if (dataGridView.DataSource == null) return;
            openFileDialog.Filter = "xml文件(*.xml)|*.xml";
            openFileDialog.Multiselect = true;
            if (openFileDialog.ShowDialog() != DialogResult.OK) return;
            foreach (string fi in openFileDialog.FileNames)
            {
                Xml2Row(fi);
            }
        }

        /// <summary>
        /// 将xml转成DataRow
        /// </summary>
        /// <param name="fullname"></param>
        private void Xml2Row(string fullname)
        {
            try
            {
                XmlDocument pXmlDoc = new XmlDocument();
                pXmlDoc.Load(fullname);
                XmlNode nodeMetaData = pXmlDoc.SelectSingleNode("MetaDataItems");
                if (nodeMetaData == null)
                {
                    nodeMetaData = pXmlDoc.SelectSingleNode("MeataDataItems");//此处是为了兼容之前写错了的元数据
                    if (nodeMetaData == null) return;
                }
                DataTable dt = dataGridView.DataSource as DataTable;
                DataRow dr = dt.NewRow();
                foreach (XmlNode pNode in nodeMetaData.ChildNodes)
                {
                    dr[MetaHelper.ID] = Guid.NewGuid().ToString();
                    if (pNode is XmlElement)
                    {
                        string fieldName = pNode.Name.Replace('、', '_').Replace('-', '_');
                        DataColumn pCol = dr.Table.Columns[fieldName];
                        if (pCol == null) continue;
                        if (pCol.DataType == typeof(float) || pCol.DataType == typeof(double))
                        {
                            double dbl = 0;
                            if (double.TryParse(pNode.InnerText, out dbl)) dr[pNode.Name] = dbl;
                        }
                        else if (pCol.DataType == typeof(short) || pCol.DataType == typeof(int) || pCol.DataType == typeof(long))
                        {
                            int ival = 0;
                            if (int.TryParse(pNode.InnerText, out ival)) dr[pNode.Name] = ival;
                        }
                        else if (pCol.DataType == typeof(DateTime))
                        {
                            DateTime time;
                            string timeStr = pNode.InnerText;
                            timeStr = timeStr.Replace('-', '/');
                            string year;
                            string month = "01";
                            string day = "01";
                            if (!timeStr.Contains('/'))
                            {
                                if (timeStr.Length >= 4)
                                {
                                    year = timeStr.Substring(0, 4);
                                    if (timeStr.Length >= 6)
                                    {
                                        month = timeStr.Substring(4, 2);
                                        if (timeStr.Length == 8)
                                        {
                                            day = timeStr.Substring(6, 2);
                                        }
                                    }
                                    timeStr = year + "/" + month + "/" + day;
                                }

                            }
                            if (DateTime.TryParse(timeStr, out time))
                                dr[pNode.Name] = time;
                        }
                        else
                        {
                            if (!String.IsNullOrWhiteSpace(pNode.InnerText))
                                //if (pNode.InnerText != null)
                                dr[fieldName] = pNode.InnerText.ToUpper();
                        }
                    }
                }
                dt.Rows.Add(dr);
            }
            catch (System.Exception ex)
            {
                LogHelper.WriteLog(new LogMessage()
                {
                    Message = "文件【" + fullname + "】导入失败：" + ex.Message,
                    LogType = zjgisLogType.zjgisLogError
                });
            }
        }

        /// <summary>
        /// 读取元数据到已有的数据行中
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnMatchXml_Click(object sender, EventArgs e)
        {
            if (dataGridView.DataSource == null) return;
            DataTable dt = dataGridView.DataSource as DataTable;
            if (dt == null) return;
            openFileDialog.Filter = "元数据(*.xml)|*.xml";
            openFileDialog.Multiselect = true;
            if (openFileDialog.ShowDialog() != DialogResult.OK) return;
            this.Cursor = Cursors.WaitCursor;
            string[] fs = openFileDialog.FileNames;
            _pgrsor.SetMaxValue(fs.Length);
            dataGridView.AllowUserToAddRows = false;
            foreach (string s in fs)
            {
                _pgrsor.Step();
                XmlDocument doc = new XmlDocument();
                try
                {
                    doc.Load(s);
                    XmlNode node = doc.SelectSingleNode("MetaDataItems");
                    if (node == null || node.ChildNodes.Count == 0) continue;
                    string rname = PlanningGIS.MetaData.MetaHelper.FindName(_SelDType.Rank.ToString(), PlanningGIS.MetaData.MetaHelper.KEY);
                    XmlNode thnd = node.SelectSingleNode("//" + rname);
                    if (thnd == null || string.IsNullOrWhiteSpace(thnd.InnerText)) continue;
                    // Linq模糊查询  
                    IEnumerable<DataGridViewRow> emList = dataGridView.Rows.Cast<DataGridViewRow>();
                    var vlist = (from item in emList
                                 where item.Cells[rname].Value != null && item.Cells[rname].Value.ToString().Equals(thnd.InnerText.ToLower(), StringComparison.CurrentCultureIgnoreCase)
                                 select item);
                    if (vlist == null) continue;
                    List<DataGridViewRow> list = vlist.ToList();
                    if (list == null || list.Count == 0) continue;
                    foreach (XmlNode nd in node.ChildNodes)
                    {
                        if (!(nd is XmlElement)) continue;
                        if (string.IsNullOrWhiteSpace(nd.InnerText)) continue;
                        if (PlanningGIS.MetaData.MetaHelper.IsSystemField(nd.Name)) continue;
                        if (!dataGridView.Columns.Contains(nd.Name)) continue;
                        foreach (DataGridViewRow r in list)
                        {
                            try
                            {
                                r.Cells[nd.Name].Value = nd.InnerText.Trim();
                            }
                            catch (Exception ex)
                            {
                                LogHelper.WriteLog("给第" + r.Index.ToString() + "行" + nd.Name + "赋值" + nd.InnerText + "失败：" + ex.Message);
                            }
                        }
                    }
                }
                catch (System.Exception err)
                {
                    MsgHelper.ShowErrorMsgbox(this, "打开数据文件失败：" + err.Message);
                }
                finally
                {
                    this.Cursor = Cursors.Default;
                    doc = null;
                }
            }
            _pgrsor.Stop();
            dataGridView.AllowUserToAddRows = true;
        }

        #endregion

        /// <summary>
        /// 删除选择
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnDelete_Click(object sender, EventArgs e)
        {
            if (dataGridView.SelectedRows.Count == 0) return;
            if (MsgHelper.ShowYesOrNoQueryMsgBox("确实要删除吗?",this) != DialogResult.Yes) return;
            DataTable dt = dataGridView.DataSource as DataTable;
            foreach (DataGridViewRow r in dataGridView.SelectedRows)
            {
                if (r.IsNewRow) continue;
                //dataGridView.Rows.Remove(r);
                if(r.DataBoundItem is DataRowView)
                    dt.Rows.Remove((r.DataBoundItem as DataRowView).Row);
            }
            dt.AcceptChanges();
        }

        /// <summary>
        /// 清除
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnClear_Click(object sender, EventArgs e)
        {
            if (dataGridView.Rows.Count == 0) return;
            if (MsgHelper.ShowYesOrNoQueryMsgBox("确实要清空吗?",this) != DialogResult.Yes) return;
            DataTable dv = dataGridView.DataSource as DataTable;
            if (dv != null)
                dv.Rows.Clear();
            else
                dataGridView.Rows.Clear();
        }

        /// <summary>
        /// 双击行标题，显示详细
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dataGridView_RowHeaderMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.RowIndex < 0) return;
            try
            {
                DataTable dt = dataGridView.DataSource as DataTable;
                FrmDetail frmDetail = new FrmDetail(dt, dataGridView.Rows[e.RowIndex]);
                frmDetail.ShowDialog(this);
            }
            catch (Exception ex)
            {
                MsgHelper.ShowErrorMsgbox(this, "打开详细异常：" + ex.Message);
            }
        }

        /// <summary>
        /// 导入空间位置
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnGeometry_Click(object sender, EventArgs e)
        {
            OpenDataDialog frm = new OpenDataDialog();
            frm.MultiSelect = false;
            if (frm.ShowDialog(this) != System.Windows.Forms.DialogResult.OK) return;
            IFeatureClass aim = null;
            try
            {
                List<ILayer> selLyr = frm.GetSelectLayers();
                if (selLyr == null || selLyr.Count == 0) return;
                IFeatureCursor source = (selLyr[0] as IFeatureLayer).FeatureClass.Search(null, false);
                IWorkspace wks = PlanningGIS.ArcGIS.WorkspaceHelper.OpenAccessWorkspace(txtFile.Text);
                string clsname = string.Format("MD_{0}_EXTENT", _SelDType.Rank.ToString());
                aim = GeodatabaseHelper.OpenFeatureClass(wks, clsname);
                if (aim == null)
                {
                    MsgHelper.ShowInfomationMsgbox(this, "范围图层" + clsname + "不存在，请检查默认是否正确");
                    return;
                }
                FeatureClassHelper.CopyFeatures(aim, source, null, null, new List<string>() { MetaHelper.METACODE }, true);
                MsgHelper.ShowInfomationMsgbox(this, "导入完成");
            }
            catch (Exception ex)
            {
                MsgHelper.ShowErrorMsgbox(this, "导入空间位置失败：" + ex.Message);
            }
        }

        /// <summary>
        /// 保存
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSave_Click(object sender, EventArgs e)
        {
            Save();
        }

        #region 导出Xml

        /// <summary>
        /// 导出Xml
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnExport_Click(object sender, EventArgs e)
        {
            if (dataGridView.Rows.Count == 0) return;
            if (chkSameFolder.Checked)
            {
                ExportXml("", false);
            }
            else
            {
                folderBrowserDialog.ShowNewFolderButton = true;
                folderBrowserDialog.Description = "选择导出路径";
                if (folderBrowserDialog.ShowDialog() != DialogResult.OK) return;
                ExportXml(folderBrowserDialog.SelectedPath, false);
            }
        }

        /// <summary>
        /// 导出选择项到XML
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnExportSelected_Click(object sender, EventArgs e)
        {
            if (chkSameFolder.Checked)
            {
                ExportXml("", true);
            }
            else
            {
                folderBrowserDialog.ShowNewFolderButton = true;
                folderBrowserDialog.Description = "选择导出路径";
                if (folderBrowserDialog.ShowDialog() != DialogResult.OK) return;
                ExportXml(folderBrowserDialog.SelectedPath, true);
            }
        }

        /// <summary>
        /// 导出元数据到xml
        /// </summary>
        /// <param name="path"></param>
        /// <param name="isSel"></param>
        private void ExportXml(string path, bool isSel)
        {
            dataGridView.AllowUserToAddRows = false;
            if (chkValid.Checked)
            {
                if (!CheckValue(isSel))
                {
                    dataGridView.AllowUserToAddRows = true;
                    return;
                }
            }
            if (isSel) _pgrsor.SetMaxValue(dataGridView.SelectedRows.Count);
            else _pgrsor.SetMaxValue(dataGridView.Rows.Count);
            int count = 0;
            bool iserr = false;
            IFeatureClass aim = null;
            if (_SelDType.Rank != zjgisRankType.TF)
            {
                try
                {
                    IWorkspace wks = PlanningGIS.ArcGIS.WorkspaceHelper.OpenAccessWorkspace(txtFile.Text);
                    if (((IWorkspace2)wks).get_NameExists(esriDatasetType.esriDTFeatureClass, _SelDType.TableName.Trim()))
                    {
                        aim = GeodatabaseHelper.OpenFeatureClass(wks, _SelDType.TableName.Trim());
                    }
                    else if (((IWorkspace2)wks).get_NameExists(esriDatasetType.esriDTTable, _SelDType.TableName.Trim()))
                    {
                        string clsname = string.Format("MD_{0}_EXTENT", _SelDType.Rank.ToString());
                        aim = GeodatabaseHelper.OpenFeatureClass(wks, clsname);
                    }
                }
                catch (Exception ex)
                {
                    LogHelper.WriteLog(ex);
                }                
            }
            IList rows = dataGridView.Rows;
            if (isSel) rows = dataGridView.SelectedRows;
            foreach (DataGridViewRow row in rows)
            {                
                if (row.IsNewRow) continue;
                if (isSel)
                    if (!row.Selected)
                        continue;
                _pgrsor.Step();
                if(chkSameFolder.Checked && row.Tag!=null)
                {
                    path = System.IO.Path.GetDirectoryName(row.Tag.ToString());
                }
                if (string.IsNullOrEmpty(path))
                {
                    string rname = MetaHelper.FindName(_SelDType.Rank.ToString(), MetaHelper.KEY);
                    LogHelper.WriteErrLog("产品数据  【" + row.Cells[rname].Value.ToString() + "】 元数据导出路径为空！");
                    continue;
                }
                if (Row2Xml(path, row, aim)) count++;
                else iserr = true;
                Application.DoEvents();
            }
            _pgrsor.Stop();
            dataGridView.AllowUserToAddRows = true;
            if (iserr)
                MsgHelper.ShowErrorMsgbox(this, "导出完毕，共导出" + count + "个元数据文件!但有部分导出失败,请查看日志。");
            else
                MsgHelper.ShowInfomationMsgbox(this, "导出完毕，共导出" + count + "个元数据文件!");
        }

        /// <summary>
        /// 检查元数据是否正确
        /// </summary>
        /// <param name="isSel"></param>
        /// <returns></returns>
        private bool CheckValue(bool isSel = false)
        {
            bool isvalid = true;
            bool issheet = true;
            _pgrsor.SetMaxValue(dataGridView.Rows.Count);
            foreach (DataGridViewRow drow in dataGridView.Rows)
            {
                if (drow.IsNewRow) continue;
                _pgrsor.Step();
                if (isSel)
                    if (!drow.Selected)
                        continue;
                if (!CheckNull(drow)) isvalid = false;
                if (_SelDType.Rank == zjgisRankType.TF)
                    if (!CheckTH(drow)) issheet = false;
            }
            _pgrsor.Stop();
            if (!isvalid) MsgHelper.ShowErrorMsgbox(this, "数据有错误，请填写完整。");
            if (!issheet)
            {
                if (MsgHelper.ShowYesOrNoQueryMsgBox("有产品数据不在标准的图幅范围内，是否确定要录入元数据？",this) == System.Windows.Forms.DialogResult.Yes)
                {
                    return true;
                }
            }
            return isvalid;
        }

        /// <summary>
        /// 空值检查，无不允许的空值则返回true
        /// </summary>
        /// <param name="drow"></param>
        /// <returns></returns>
        private bool CheckNull(DataGridViewRow drow)
        {
            if (_RuleFields == null || _RuleFields.Count == 0) return true;
            bool isvalid = true;
            foreach (MetaField fd in _RuleFields)
            {
                if (dataGridView.Columns[fd.Name] == null) continue;
                drow.Cells[fd.Name].Style.BackColor = Color.White;
                if (!fd.AllowNull)
                {
                    if (drow.Cells[fd.Name].Value == null || drow.Cells[fd.Name].Value == DBNull.Value ||
                        string.IsNullOrEmpty(drow.Cells[fd.Name].Value.ToString()) ||
                        string.IsNullOrWhiteSpace(drow.Cells[fd.Name].Value.ToString()))
                    {
                        isvalid = false;
                        drow.Cells[fd.Name].Style.BackColor = Color.Red;
                    }
                }
            }
            return isvalid;
        }

        /// <summary>
        /// 检查图号，图号在图幅结合表中则返回true
        /// </summary>
        /// <param name="drow"></param>
        /// <returns></returns>
        private bool CheckTH(DataGridViewRow drow)
        {
            try
            {
                object objScale = drow.Cells[PlanningGIS.MetaData.MetaHelper.BLCFM].Value;
                if (objScale == null || string.IsNullOrWhiteSpace(objScale.ToString()))
                {
                    drow.Cells[PlanningGIS.MetaData.MetaHelper.BLCFM].Style.BackColor = Color.Red;
                    return false;
                }
                int scale = 0;
                if (!int.TryParse(objScale.ToString(), out scale))
                {
                    drow.Cells[PlanningGIS.MetaData.MetaHelper.BLCFM].Style.BackColor = Color.Red;
                    return false;
                }
                string rname = PlanningGIS.MetaData.MetaHelper.FindName(_SelDType.Rank.ToString(), PlanningGIS.MetaData.MetaHelper.KEY);
                object objth = drow.Cells[rname].Value;
                if (objth == null || string.IsNullOrWhiteSpace(objth.ToString()))
                {
                    drow.Cells[rname].Style.BackColor = Color.Red;
                    return false;
                }
                if (!JHBHelper.CheckCode(objth.ToString(), scale))
                {
                    drow.Cells[rname].Style.BackColor = Color.Red;
                    return false;
                }
                return true;
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog("检查数据时异常，可能是系统数据不满足要求。" + ex.ToString());
                return false;
            }            
        }
        
        /// <summary>
        /// 将元数据列转成Xml
        /// </summary>
        /// <param name="savepath">要保存的路径</param>
        /// <param name="row">元数据列</param>
        /// <param name="featcls">空间位置图层</param>
        /// <returns></returns>
        private bool Row2Xml(string savepath, DataGridViewRow row, IFeatureClass featcls = null)
        {
            string rname = MetaHelper.FindName(_SelDType.Rank.ToString(), MetaHelper.KEY);
            string th = row.Cells[rname].Value.ToString().Trim();            
            XmlDocument doc = new XmlDocument();
            try
            {
                XmlElement pElemItems = doc.CreateElement("MetaDataItems");
                doc.AppendChild(pElemItems);
                int scale = 0;
                foreach (DataGridViewColumn pColumn in dataGridView.Columns)
                {
                    string name = pColumn.Name.Trim();
                    if (MetaHelper.ID.Equals(name, StringComparison.CurrentCultureIgnoreCase)) continue;
                    if (name.Contains("、") || name.Contains("-"))
                    {
                        LogHelper.WriteLog("元数据中["+name+"]字段包含‘、’或‘-’符号，不满足数据库要求！");
                        name = name.Replace("、", "_");
                        name = name.Replace("-", "_");
                    }
                    XmlElement pElemItem = doc.CreateElement(name);
                    if (row.Cells[pColumn.Name].Value is DateTime)
                    {
                        pElemItem.InnerText = row.Cells[pColumn.Name].Value == null ? "" : ((DateTime)row.Cells[pColumn.Name].Value).ToShortDateString();
                    }
                    else
                    {
                        pElemItem.InnerText = row.Cells[pColumn.Name].Value == null ? "" : row.Cells[pColumn.Name].Value.ToString();
                    }
                    if (name.Equals(MetaHelper.BLCFM, StringComparison.CurrentCultureIgnoreCase))
                    {
                        int.TryParse(pElemItem.InnerText, out scale);
                    }
                    pElemItems.AppendChild(pElemItem);
                }
                string wkt = "";
                if (featcls != null && featcls.FeatureCount(null) > 0)
                {
                    if (((IDataset)featcls).Name == _SelDType.TableName)
                    {
                        IFeature feat = featcls.GetFeature(Convert.ToInt32(row.Cells["OBJECTID"].Value.ToString().Trim()));
                        if (feat != null && !feat.Shape.IsEmpty)
                        {
                            IXMLWriter pWriter = new XMLWriter();
                            IXMLStream pStream = new XMLStream();
                            pWriter.WriteTo(pStream as IStream);

                            IXMLSerializer pSerializer = new XMLSerializer();
                            pSerializer.WriteObject(pWriter, null, null, "Shape", "", feat.Shape);
                            wkt = pStream.SaveToString();
                            //wkt = feat.Shape.ToWkt();
                        }
                    }
                    else
                    {
                        int index = featcls.Fields.FindField(MetaHelper.METACODE);
                        if (index >= 0)
                        {
                            IQueryFilter flt = new QueryFilter();
                            flt.WhereClause = MetaHelper.METACODE + " = '" + row.Cells[rname].Value.ToString() + "'";
                            IFeatureCursor featCur = featcls.Search(flt, false);
                            IFeature feat = featCur.NextFeature();
                            if (feat != null && !feat.Shape.IsEmpty)
                            {
                                IXMLWriter pWriter = new XMLWriter();
                                IXMLStream pStream = new XMLStream();
                                pWriter.WriteTo(pStream as IStream);

                                IXMLSerializer pSerializer = new XMLSerializer();
                                pSerializer.WriteObject(pWriter, null, null, "Shape", "", feat.Shape);
                                wkt = pStream.SaveToString();
                                //wkt = feat.Shape.ToWkt();
                            }
                        }
                    }

                }
                else
                {
                    if (scale > 0)
                    {
                        featcls = JHBHelper.GetFeatureClass(scale);
                        if (_SelDType.Rank == zjgisRankType.TF)
                        {
                            if (featcls != null)
                            {
                                IQueryFilter flt = new QueryFilter();
                                flt.WhereClause = rname + "  = '" + row.Cells[rname].Value.ToString() + "'";
                                IFeatureCursor featCur = featcls.Search(flt, false);
                                IFeature feat = featCur.NextFeature();
                                if (feat != null && !feat.Shape.IsEmpty)
                                {
                                    IXMLWriter pWriter = new XMLWriter();
                                    IXMLStream pStream = new XMLStream();
                                    pWriter.WriteTo(pStream as IStream);

                                    IXMLSerializer pSerializer = new XMLSerializer();
                                    pSerializer.WriteObject(pWriter, null, null, "Shape", "", feat.Shape);
                                    wkt = pStream.SaveToString();

                                    //wkt = feat.Shape.ToWkt();
                                }
                            }
                        }
                        else//添加无测区范围情况，可以从数据中自动获取
                        {
                            //ISpatialReference pSpatialRef = (featcls as IGeoDataset).SpatialReference;
                            IEnvelope pEnv = new ESRI.ArcGIS.Geometry.Envelope() as IEnvelope;
                            if (row.Tag != null)
                            {
                                string FullName = row.Tag.ToString();
                                if (FullName.EndsWith(".dwg", StringComparison.CurrentCultureIgnoreCase))
                                {
                                    ICadLayer pCadLayer = CadHelper.GetCadLayer(row.Tag.ToString());
                                    //pCadLayer.SpatialReference = pSpatialRef;
                                    pEnv = pCadLayer.AreaOfInterest;
                                }
                                else if (FullName.EndsWith(".img", StringComparison.CurrentCultureIgnoreCase) || FullName.EndsWith(".tif", StringComparison.CurrentCultureIgnoreCase))
                                {
                                    IWorkspaceFactory workspcFac = new RasterWorkspaceFactory();
                                    IRasterDataset rasterDatst = new RasterDatasetClass();
                                    IRasterLayer rasterLay = new RasterLayerClass();
                                    IRasterWorkspace rasterWorkspc = workspcFac.OpenFromFile(System.IO.Path.GetDirectoryName(FullName), 0) as IRasterWorkspace;
                                    rasterDatst = rasterWorkspc.OpenRasterDataset(System.IO.Path.GetFileName(FullName));
                                    rasterLay.CreateFromDataset(rasterDatst);
                                    IRaster pRaster = rasterLay.Raster;
                                    IGeoDataset pInGeoDs = pRaster as IGeoDataset;
                                    pEnv = pInGeoDs.Extent;
                                }
                                if (pEnv != null)
                                {
                                    IPolygon poly = GeometryHelper.ExtentToPolygon(pEnv.LowerLeft.X, pEnv.LowerLeft.Y, pEnv.UpperRight.X, pEnv.UpperRight.Y);

                                    IXMLWriter pWriter = new XMLWriter();
                                    IXMLStream pStream = new XMLStream();
                                    pWriter.WriteTo(pStream as IStream);

                                    IXMLSerializer pSerializer = new XMLSerializer();
                                    pSerializer.WriteObject(pWriter, null, null, "Shape", "", poly);
                                    wkt = pStream.SaveToString();

                                    //wkt = feat.Shape.ToWkt();
                                }
                            }
                        }
                    }
                }
                XmlElement geoItem = doc.CreateElement(MetaHelper.GEOMETRY);
                geoItem.InnerText = wkt;
                pElemItems.AppendChild(geoItem);
                string path = savepath;
                if (chkFDCreate.Checked && !string.IsNullOrWhiteSpace(cmbColumn.Text))
                {
                    try
                    {
                        object o = row.Cells[cmbColumn.Text].Value;
                        if (o != null)
                        {
                            string name = o.ToString();
                            if (MetaHelper.SCRQ.Equals(cmbColumn.Text, StringComparison.CurrentCultureIgnoreCase))
                                name = DateTime.Parse(name).ToString("yyyy-MM");
                            path = savepath + "\\" + name;
                            if (!Directory.Exists(path)) Directory.CreateDirectory(path);
                        }
                    }
                    catch
                    {

                    }
                }
                string fname = path + "\\" + th + ".xml";
                int idx = 2;
                while (System.IO.File.Exists(fname))
                {
                    if (idx == 2) LogHelper.WriteErrLog("图号或测试代号【" + th + "】在同一批次中有重复");
                    fname = path + "\\" + th + "_" + idx.ToString() + ".xml";
                    idx++;
                }
                doc.Save(fname);
                if (chkExpGrid.Checked)
                {
                    string gf = path + "\\" + th + ".grd";
                    if (!File.Exists(gf)) File.Create(gf);
                }
                return true;
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(new LogMessage()
                {
                    Message = "导出元数据失败：" + ex.Message,
                    LogType = zjgisLogType.zjgisLogNormal
                });
                return false;
            }
            finally
            {
                doc = null;
            }
        }
        
        #endregion

        #region 验证
        /// <summary>
        /// 验证单元格的值
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dataGridView_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
        {
            try
            {
                dataGridView.Rows[e.RowIndex].ErrorText = string.Empty;
                if (e.FormattedValue == null || string.IsNullOrEmpty(e.FormattedValue.ToString())) return;
                string value = e.FormattedValue.ToString();
                DataTable dt = (DataTable)dataGridView.DataSource;
                string colname = dt.Columns[e.ColumnIndex].ColumnName;
                string rname = PlanningGIS.MetaData.MetaHelper.FindName(_SelDType.Rank.ToString(), PlanningGIS.MetaData.MetaHelper.KEY);
                Type tp = dt.Columns[e.ColumnIndex].DataType;
                if (tp == typeof(DateTime))
                    dataGridView.Rows[e.RowIndex].ErrorText = "时间格式错误";
                else if (tp == typeof(int) || tp == typeof(double))
                    dataGridView.Rows[e.RowIndex].ErrorText = "数字格式错误";
            }
            catch (Exception ex)
            {
                MsgHelper.ShowErrorMsgbox(this, ex.Message);
            }
        }

        /// <summary>
        /// 验证触发异常时，显示错误提示
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dataGridView_DataError(object sender, DataGridViewDataErrorEventArgs e)
        {
            if (!e.ThrowException && e.Exception != null)
            {
                FrmNotify.ShowNotify(dataGridView.Rows[e.RowIndex].ErrorText + ":" + e.Exception.Message, 5);
                dataGridView[e.ColumnIndex, e.RowIndex].Selected = true;
                dataGridView.CurrentCell = dataGridView[e.ColumnIndex, e.RowIndex];
                e.Cancel = true;
            }
        }

        /// <summary>
        /// 停止编辑时，清除所有错误
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dataGridView_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            dataGridView.Rows[e.RowIndex].ErrorText = string.Empty;
        }
        
        /// <summary>
        /// 添加列，不允许排序
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dataGridView_ColumnAdded(object sender, DataGridViewColumnEventArgs e)
        {
            e.Column.SortMode = DataGridViewColumnSortMode.NotSortable;
        }
        #endregion

        /// <summary>
        /// 退出
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnClose_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        /// <summary>
        /// 正在关闭窗体
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FrmMetaData_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (MsgHelper.ShowYesOrNoQueryMsgBox("确定要退出吗?") != DialogResult.Yes)
            {
                e.Cancel = true;
                return;
            }
            Save();
        }

        #region 读取范围

        /// <summary>
        /// 从CAD的范围线中导入元数据的范围
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnImpFWX_Click(object sender, EventArgs e)
        {
            string clsname = string.Format("MD_{0}_EXTENT", _SelDType.Rank.ToString());
            IFeatureClass aim = null;
            IWorkspace wks = null;
            try
            {
                wks = PlanningGIS.ArcGIS.WorkspaceHelper.OpenAccessWorkspace(txtFile.Text);
                aim = GeodatabaseHelper.OpenFeatureClass(wks, clsname);
                if (aim == null)
                {
                    aim = null;
                    wks = null;
                    MsgHelper.ShowInfomationMsgbox(this, "范围图层" + clsname + "不存在，请检查默认是否正确");
                    return;
                }
            }
            catch (Exception ex)
            {
                aim = null;
                wks = null;
                MsgHelper.ShowErrorMsgbox(this, "获取空间范围图层" + clsname + "失败：" + ex.Message);
                return;
            }
            //test(aim);
            //return;

            openFileDialog.Filter = "CAD文件(*.dwg;*.dgn)|*.dwg;*.dgn";
            openFileDialog.Multiselect = true;
            if (openFileDialog.ShowDialog(this) != System.Windows.Forms.DialogResult.OK) return;
            string[] files = openFileDialog.FileNames;
            string savepath = AppConfig.StartupPath + @"\Temp\Dwg2GeoDb";
            if (!Directory.Exists(savepath)) Directory.CreateDirectory(savepath);
            FrameworkHelper.ShowLogPanel();            
            _pgrsor.SetMaxValue(files.Length * 2);
            this.Cursor = Cursors.WaitCursor;
            try
            {
                LogHelper.WriteLog("开始转换CAD文件，并将转换后的文件保存到：" + savepath);
                //Dwg2Shp(files, savepath);
                Dwg2Geodatabase(files, savepath);
                LogHelper.WriteLog(new LogMessage()
                {
                    Message = "范围线转换成功，开始写入范围线到范围图层中。",
                    LogType = zjgisLogType.zjgisLogNormal
                });
                //Line2Poly(files, savepath,aim);
                Line2PolyGeo(files, savepath, aim);
                MsgHelper.ShowInfomationMsgbox(this, "导入完成，请查看详细信息");
                try
                {
                    Directory.Delete(savepath);
                }
                catch
                {

                }
            }
            catch (Exception ex)
            {
                MsgHelper.ShowErrorMsgbox(this, ex.Message);
            }
            finally
            {
                this.Cursor = Cursors.Default;
            }
            aim = null;
            wks = null;
            
        }

        /// <summary>
        /// 将从DWG中提取范围线数据
        /// </summary>
        /// <param name="files">要提取的DWG文件</param>
        /// <param name="savepath">保存到的路径</param>
        private void Dwg2Shp(string[] files, string savepath)
        {
            if (files == null || files.Length == 0) return;
            foreach (string fi in files)
            {
                _pgrsor.Step();
                try
                {
                    FeatureClassToShapefile gp = new FeatureClassToShapefile();
                    gp.Input_Features = fi + "\\Polyline";
                    gp.Output_Folder = savepath;
                    GeoprocessorHelper.Execute(gp);
                    string fname = System.IO.Path.GetFileNameWithoutExtension(fi);
                    string ext = System.IO.Path.GetExtension(fi);
                    string lyrname = fname + "_" + ext.Replace(".", "").Trim() + "_Polyline.shp";
                    if (!(File.Exists(lyrname))) LogHelper.WriteLog(new LogMessage()
                    {
                        Message = fi + "转换失败：" + GeoprocessorHelper.GetMessage(),
                        LogType = zjgisLogType.zjgisLogError
                    });
                    else LogHelper.WriteLog(new LogMessage()
                    {
                        Message = fi + "转换成功。",
                        LogType = zjgisLogType.zjgisLogNormal
                    });
                }
                catch (Exception ex)
                {
                    LogHelper.WriteLog(new LogMessage()
                    {
                        Message = fi + "转换失败：" + ex.Message,
                        LogType = zjgisLogType.zjgisLogError
                    });
                }                
                Application.DoEvents();
            }
            Application.DoEvents();
            LogHelper.WriteLog(new LogMessage()
            {
                Message = "范围线转换完成。",
                LogType = zjgisLogType.zjgisLogDone
            });
        }

        /// <summary>
        /// 将从DWG中提取范围线数据
        /// </summary>
        /// <param name="files">要提取的DWG文件</param>
        /// <param name="savepath">保存到的路径</param>
        private void Dwg2Geodatabase(string[] files, string savepath)
        {
            if (files == null || files.Length == 0) return;
            foreach (string fi in files)
            {
                _pgrsor.Step();
                try
                {
                    string wksname = savepath + "\\" + System.IO.Path.GetFileNameWithoutExtension(fi) + ".gdb";
                    IWorkspace wks = PlanningGIS.ArcGIS.WorkspaceHelper.CreateGDBWorkspace(wksname);
                    CADToGeodatabase gp = new CADToGeodatabase();
                    gp.input_cad_datasets = fi;
                    gp.out_dataset_name = "CADToGeodatabase";
                    gp.out_gdb_path = wksname;
                    gp.reference_scale = 1000;
                    GeoprocessorHelper.Execute(gp);
                    if (!((IWorkspace2)wks).get_NameExists(esriDatasetType.esriDTFeatureClass, "Polyline"))
                        LogHelper.WriteLog(new LogMessage()
                        {
                            Message = fi + "转换失败：" + GeoprocessorHelper.GetMessage(),
                            LogType = zjgisLogType.zjgisLogError
                        });
                    else
                        LogHelper.WriteLog(new LogMessage()
                        {
                            Message = fi + "转换成功。",
                            LogType = zjgisLogType.zjgisLogNormal
                        });
                }
                catch (Exception ex)
                {
                    LogHelper.WriteLog(new LogMessage()
                    {
                        Message = fi + "转换失败：" + ex.Message,
                        LogType = zjgisLogType.zjgisLogError
                    });
                }
                Application.DoEvents();
            }
            Application.DoEvents();
            LogHelper.WriteLog(new LogMessage()
            {
                Message = "范围线转换完成。",
                LogType = zjgisLogType.zjgisLogDone
            });
        }

        /// <summary>
        /// 将提取的范围线转成面
        /// </summary>
        /// <param name="files"></param>
        /// <param name="savepath"></param>
        /// <param name="tofeatcls"></param>
        private void Line2Poly(string[] files, string savepath, IFeatureClass tofeatcls)
        {
            if (files == null || files.Length == 0) return;
            IWorkspace wks = null;
            IFeatureCursor inCur = null;
            try
            {
                int idx = tofeatcls.Fields.FindField(MetaHelper.METACODE);
                if (idx < 0)
                {
                    LogHelper.WriteLog(new LogMessage()
                    {
                        Message = "空间图层中不存在字段：" + MetaHelper.METACODE,
                        LogType = zjgisLogType.zjgisLogError
                    });
                    return;
                }
                wks = PlanningGIS.ArcGIS.WorkspaceHelper.OpenShpWorkspace(savepath);
                inCur = tofeatcls.Insert(true);
                foreach (string fi in files)
                {
                    _pgrsor.Step();
                    try
                    {
                        //string lyrname = System.IO.Path.GetFileNameWithoutExtension(fi);
                        string fname = System.IO.Path.GetFileNameWithoutExtension(fi);
                        string ext = System.IO.Path.GetExtension(fi);
                        string lyrname = fname + "_" + ext.Replace(".", "").Trim() + "_Polyline";
                        IFeatureClass featcls = GeodatabaseHelper.OpenFeatureClass(wks, lyrname);
                        if (featcls == null)
                        {
                            LogHelper.WriteLog(new LogMessage()
                            {
                                Message = fi + "非空间图层!",
                                LogType = zjgisLogType.zjgisLogError
                            });
                            continue;
                        }
                        IFeatureCursor cur = featcls.Search(null, false);
                        IFeature feat = null;
                        List<IGeometry> polys = new List<IGeometry>();
                        while ((feat = cur.NextFeature()) != null)
                        {
                            if (feat.Shape == null || feat.Shape.IsEmpty) continue;
                            try
                            {
                                IPolyline l = feat.ShapeCopy as IPolyline;
                                ICurve curve = l as ICurve;
                                if (!curve.IsClosed)
                                {
                                    LogHelper.WriteLog(new LogMessage()
                                    {
                                        Message = "【" + lyrname + "】中的【" + feat.OID.ToString() + "】不是闭合的线，不能转成面!",
                                        LogType = zjgisLogType.zjgisLogError
                                    });
                                    continue;
                                }
                                IPolygon py = new Polygon() as IPolygon;
                                (py as IPointCollection).AddPointCollection(l as IPointCollection);
                                polys.Add(py);
                            }
                            catch (Exception ex)
                            {
                                LogHelper.WriteLog(new LogMessage()
                                {
                                    Message = "将【" + lyrname + "】中的【" + feat.OID.ToString() + "】转成面失败：" + ex.Message,
                                    LogType = zjgisLogType.zjgisLogError
                                });
                            }
                        }
                        if (polys.Count == 0)
                        {
                            cur = null;
                            LogHelper.WriteLog(new LogMessage()
                            {
                                Message = fi + "中不存在空间范围!",
                                LogType = zjgisLogType.zjgisLogError
                            });
                            continue;
                        }
                        IFeatureBuffer newfeat = tofeatcls.CreateFeatureBuffer();
                        newfeat.set_Value(idx, fname);
                        newfeat.Shape = polys.Count == 1 ? polys[0] : GeometryHelper.Union(polys);
                        inCur.InsertFeature(newfeat);
                        LogHelper.WriteLog(new LogMessage()
                        {
                            Message = fi + "导入成功。",
                            LogType = zjgisLogType.zjgisLogNormal
                        });
                        cur = null;
                        feat = null;
                        newfeat = null;
                    }
                    catch (Exception ex)
                    {
                        LogHelper.WriteLog(new LogMessage()
                        {
                            Message = fi + "转换失败：" + ex.Message,
                            LogType = zjgisLogType.zjgisLogError
                        });
                    }
                    Application.DoEvents();
                }
                inCur.Flush();
                Application.DoEvents();
                LogHelper.WriteLog(new LogMessage()
                {
                    Message = "空间范围导入完成" ,
                    LogType = zjgisLogType.zjgisLogDone
                });
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(new LogMessage()
                {
                    Message = "导入范围是发生异常：" + ex.Message,
                    LogType = zjgisLogType.zjgisLogError
                });
            }
            finally
            {
                wks = null;
                inCur = null;
            }
        }

        /// <summary>
        /// 将提取的范围线转成面
        /// </summary>
        /// <param name="files"></param>
        /// <param name="savepath"></param>
        /// <param name="tofeatcls"></param>
        private void Line2PolyGeo(string[] files, string savepath, IFeatureClass tofeatcls)
        {
            if (files == null || files.Length == 0) return;
            IFeatureCursor inCur = null;
            try
            {
                int idx = tofeatcls.Fields.FindField(MetaHelper.METACODE);
                if (idx < 0)
                {
                    LogHelper.WriteLog(new LogMessage()
                    {
                        Message = "空间图层中不存在字段：" + MetaHelper.METACODE,
                        LogType = zjgisLogType.zjgisLogError
                    });
                    return;
                }
                inCur = tofeatcls.Insert(true);
                foreach (string fi in files)
                {
                    _pgrsor.Step();
                    try
                    {
                        string lyrname = System.IO.Path.GetFileNameWithoutExtension(fi);
                        string wksname = savepath + "\\" + lyrname + ".gdb";
                        IWorkspace wks = PlanningGIS.ArcGIS.WorkspaceHelper.OpenGDBWorkspace(wksname);
                        IFeatureClass featcls = GeodatabaseHelper.OpenFeatureClass(wks, "Polyline");
                        if (featcls == null)
                        {
                            LogHelper.WriteLog(new LogMessage()
                            {
                                Message = fi + "非空间图层!",
                                LogType = zjgisLogType.zjgisLogError
                            });
                            continue;
                        }
                        IFeatureCursor cur = featcls.Search(null, false);
                        IFeature feat = null;
                        List<IGeometry> polys = new List<IGeometry>();
                        while ((feat = cur.NextFeature()) != null)
                        {
                            if (feat.Shape == null || feat.Shape.IsEmpty) continue;
                            try
                            {
                                IPolyline l = feat.ShapeCopy as IPolyline;
                                ICurve curve = l as ICurve;
                                if (!curve.IsClosed)
                                {
                                    LogHelper.WriteLog(new LogMessage()
                                    {
                                        Message = "【" + lyrname + "】中的【" + feat.OID.ToString() + "】不是闭合的线，不能转成面!",
                                        LogType = zjgisLogType.zjgisLogError
                                    });
                                    continue;
                                }
                                IPolygon py = new Polygon() as IPolygon;
                                (py as IPointCollection).AddPointCollection(l as IPointCollection);
                                polys.Add(py);
                            }
                            catch (Exception ex)
                            {
                                LogHelper.WriteLog(new LogMessage()
                                {
                                    Message = "将【" + lyrname + "】中的【" + feat.OID.ToString() + "】转成面失败：" + ex.Message,
                                    LogType = zjgisLogType.zjgisLogError
                                });
                            }
                        }
                        if (polys.Count == 0)
                        {
                            cur = null;
                            LogHelper.WriteLog(new LogMessage()
                            {
                                Message = fi + "中不存在空间范围!",
                                LogType = zjgisLogType.zjgisLogError
                            });
                            continue;
                        }
                        IFeatureBuffer newfeat = tofeatcls.CreateFeatureBuffer();
                        newfeat.set_Value(idx, lyrname);
                        newfeat.Shape = polys.Count == 1 ? polys[0] : GeometryHelper.Union(polys);
                        inCur.InsertFeature(newfeat);
                        LogHelper.WriteLog(new LogMessage()
                        {
                            Message = fi + "导入成功。",
                            LogType = zjgisLogType.zjgisLogNormal
                        });
                        cur = null;
                        feat = null;
                        newfeat = null;
                        wks = null;
                    }
                    catch (Exception ex)
                    {
                        LogHelper.WriteLog(new LogMessage()
                        {
                            Message = fi + "转换失败：" + ex.Message,
                            LogType = zjgisLogType.zjgisLogError
                        });
                    }
                    Application.DoEvents();
                }
                inCur.Flush();
                Application.DoEvents();
                LogHelper.WriteLog(new LogMessage()
                {
                    Message = "空间范围导入完成",
                    LogType = zjgisLogType.zjgisLogDone
                });
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(new LogMessage()
                {
                    Message = "导入范围是发生异常：" + ex.Message,
                    LogType = zjgisLogType.zjgisLogError
                });
            }
            finally
            {
                
                inCur = null;
            }
        }
        #endregion

        private void btnAutoUpdate_Click(object sender, EventArgs e)
        {
            if (_SelDType.Rank != zjgisRankType.TF)
            {
                MsgHelper.ShowInfomationMsgbox("当前选择的不是分幅产品数据！");
                return;
            }
            MetaRule rule = null;
            if (ProductHelper.MetaRules != null && ProductHelper.MetaRules.Count > 0)
                rule = ProductHelper.MetaRules.FirstOrDefault(t => t.TableName.Equals(_SelDType.TableName, StringComparison.CurrentCultureIgnoreCase));
            List<MetaField> fds = rule.Fields.FindAll(t => t.AutoValueType != zjgisAutoValueType.zjgisAutoValueUnKnow);
            DataTable dt = dataGridView.DataSource as DataTable;
            try
            { 

                IMapsheet sheet = new LowerLeftMapsheet()
                {
                    UnitValue = SheetHelper.Config.UnitValue
                };
                string SizeStrFormat = SheetHelper.Config.CurrentSize;
                if (swtSizeType.Value == true) SizeStrFormat = swtSizeType.OnText;
                else SizeStrFormat = swtSizeType.OffText;
                sheet.SizeString = SheetHelper.Config.SizeTypes.FirstOrDefault(t => string.Equals(SizeStrFormat, t.Name, StringComparison.CurrentCultureIgnoreCase)).Value;
                string rname = PlanningGIS.MetaData.MetaHelper.FindName(_SelDType.Rank.ToString(), PlanningGIS.MetaData.MetaHelper.KEY);
                int failedCount = 0;
                foreach (DataRow pRow in dt.Rows)
                {
                    object th = pRow[rname];
                    if (th == DBNull.Value)
                    {
                        failedCount++;
                        continue;
                    }
                    string strMapNo = th.ToString().Trim();

                    object scale = pRow[MetaHelper.BLCFM];
                    if (scale == DBNull.Value)
                    {
                        LogHelper.WriteErrLog(string.Format("图号为{0}的图幅信息自动读取失败，比例尺分母不能为空。", strMapNo));
                        failedCount++;
                        continue;
                    }
                    string scaleValue = scale.ToString().Trim();
                    SheetScale sheetScale = SheetHelper.Config.ScaleTypes.FirstOrDefault(t => string.Equals(t.Value.ToString(), scaleValue, StringComparison.CurrentCultureIgnoreCase));
                    if (sheetScale == null)
                    {
                        LogHelper.WriteErrLog(string.Format("图号为{0}的图幅信息自动读取失败，未能在配置文件中找到对应的比例尺信息{1}。", strMapNo, scaleValue));
                        failedCount++;
                        continue;
                    }
                    Mapsheet mapSheet = sheet.GetMapSheet(strMapNo, sheetScale);
                    if (mapSheet == null)
                    {
                        LogHelper.WriteErrLog(string.Format("图号为{0}的图幅信息自动读取失败，图幅获取失败，请检查配置文件的图幅格式。", strMapNo, scaleValue));
                        failedCount++;
                        continue;
                    }
                    List<Mapsheet> roundSheets = sheet.GetMapSheets(strMapNo, sheetScale);
                    foreach (MetaField autoFd in fds)
                    {
                        switch (autoFd.AutoValueType)
                        {
                            case zjgisAutoValueType.zjgisAutoValueTHEast:
                                pRow[autoFd.Name] = roundSheets[5].Code;
                                break;
                            case zjgisAutoValueType.zjgisAutoValueTHEN:
                                pRow[autoFd.Name] = roundSheets[2].Code;
                                break;
                            case zjgisAutoValueType.zjgisAutoValueTHES:
                                pRow[autoFd.Name] = roundSheets[8].Code;
                                break;
                            case zjgisAutoValueType.zjgisAutoValueTHNorth:
                                pRow[autoFd.Name] = roundSheets[1].Code;
                                break;
                            case zjgisAutoValueType.zjgisAutoValueTHSouth:
                                pRow[autoFd.Name] = roundSheets[7].Code;
                                break;
                            case zjgisAutoValueType.zjgisAutoValueTHWest:
                                pRow[autoFd.Name] = roundSheets[3].Code;
                                break;
                            case zjgisAutoValueType.zjgisAutoValueTHWN:
                                pRow[autoFd.Name] = roundSheets[0].Code;
                                break;
                            case zjgisAutoValueType.zjgisAutoValueTHWS:
                                pRow[autoFd.Name] = roundSheets[6].Code;
                                break;
                            case zjgisAutoValueType.zjgisAutoValueXEN:
                                pRow[autoFd.Name] = mapSheet.Geometry.Envelope.UpperRight.X.ToString();
                                break;
                            case zjgisAutoValueType.zjgisAutoValueXWS:
                                pRow[autoFd.Name] = mapSheet.Geometry.Envelope.LowerLeft.X.ToString();
                                break;
                            case zjgisAutoValueType.zjgisAutoValueYEN:
                                pRow[autoFd.Name] = mapSheet.Geometry.Envelope.UpperRight.Y.ToString();
                                break;
                            case zjgisAutoValueType.zjgisAutoValueYWS:
                                pRow[autoFd.Name] = mapSheet.Geometry.Envelope.LowerLeft.Y.ToString();
                                break;
                            case zjgisAutoValueType.zjgisAutoValueDataType:
                                pRow[autoFd.Name] = mapSheet.Geometry.Envelope.LowerLeft.Y.ToString();
                                break;
                            default:
                                break;
                        }

                    }
                }
                if (failedCount > 0)
                {
                    MsgHelper.ShowInfomationMsgbox("共有" + failedCount + "条记录更新失败,原因：图号、比例尺分母为空或不正确！");
                }
                else
                {
                    MsgHelper.ShowInfomationMsgbox("自动更新完成！");
                }
            }
            catch (Exception ex)
            {
                MsgHelper.ShowErrorMsgbox("自动更新出错：" + ex.Message);
            }
            
        }
    }
}